## JAGS code of the model used in the manuscript "A path reconstruction method 
## integrating dead-reckoning and position fixes applied to humpback whales"
## by Paul Wensveen, Len Thomas, and Patrick Miller for Movement Ecology.

data {
    pi <- 3.141592653589
    pi2 <- 2*pi
    rho <- 0.897326  # wCauchy concentration parameter
    firstsd <- ifelse(m[1]-1, (0.1*R[1]), (0.302*R[1])) # sd of first location if visual   
    }

model  
{

## Priors
sigma[1] ~ dunif(0, 0.1)  # Process noise sd, x
sigma[2] ~ dunif(0, 0.1)  # Process noise sd, y

## variance-covariance precision matrix
iSigma[1,1] <- sigma[1]^(-2)
iSigma[1,2] <- 0
iSigma[2,1] <- 0
iSigma[2,2] <- sigma[2]^(-2)

## Priors on 1st position depend upon observation type (visual or FGPS)
x1[1,1] ~ dt(0, tauF[1,1], nuF[1,1])
x1[1,2] ~ dt(0, tauF[1,2], nuF[1,2])
x2[1,1] ~ dnorm(0, firstsd^(-2))
x2[1,2] ~ dnorm(0, firstsd^(-2))
x[1,1:2] <- ifelse(type-1, x2[1, ], x1[1, ])
    
## Priors on 1st velocity correction
vcor[1,1] ~ dunif(-1, 1)
vcor[1,2] ~ dunif(-1, 1)

## 2nd whale position = first position + displacement from DR + velocity correction*delta
x[2,1] <- x[1,1] + ddrx[1] + vcor[1,1]/1000*delta[1]
x[2,2] <- x[1,2] + ddry[1] + vcor[1,2]/1000*delta[1]

## CRW process on velocity correction
for(j in 2:N-1){
    vcor[j,1:2] ~ dmnorm(vcor[j-1,], iSigma[,]/delta[j])

    ## Update whale position  
    x[j+1,1] <- x[j,1] + ddrx[j] + vcor[j,1]/1000*delta[j]
    x[j+1,2] <- x[j,2] + ddry[j] + vcor[j,2]/1000*delta[j]
}

## Observation model for FGPS data
for(j in 1:N){
    for(k in (idxF[j]):(idxF[j+1]-1)){
        XFx[k] ~ dt(x[j,1], tauF[k,1], nuF[k,1])
        XFy[k] ~ dt(x[j,2], tauF[k,2], nuF[k,2])
    }
}

## Observation model for visual data
for(j in 1:N){				
    for(k in (idxb[j]):(idxb[j+1]-1)){
        dbwx[k] <- x[j,1] - Xbx[k]   # boat-whale orthogonal distance, x
        dbwy[k] <- x[j,2] - Xby[k]   # boat-whale orthogonal distance, y
        
        ## Boat-whale range without error
        r[k] <- sqrt(dbwx[k]^2 + dbwy[k]^2) 

        ## Boat-whale range with error depends upon measurement type
        R[k] ~ dnorm(r[k], rangesd[k]^(-2))
        rangesd[k] <- ifelse(m[k]-1, 0.1*r[k], 0.302*r[k])

        ## Bearing without error using four-quadrant arc tangent (-pi,pi]
        at[k] <- atan(dbwx[k] / dbwy[k])
        phi[k] <- ifelse(step(dbwy[k]), at[k], pi2*step(dbwx[k])+at[k]-pi)

        ## Ones trick for bearing with error [i.e. Phi[i] ~ wC(phi[k], rho)]
        wC[k] <- (1/pi2 * (1-rho^2) / (1+rho^2 - 2*rho*cos(Phi[k] - phi[k])))/1000
        ones[k] ~ dbern(wC[k])
    }
}
}

